(function ($) {

    Drupal.behaviors.cm = {
        attach: function (context, settings) {

            var tags = {
                "!top": ["TEI"],
                TEI: {
                    children: ["teiHeader", "text"]
                },
                teiHeader: {
                    attrs: {
                        name: null,
                    },
                    children: ["fileDesc", "encodingDesc", "profileDesc", "revisionDesc"]
                },
		fileDesc: {
			attrs: {
				name: null,
			},
			children: ["titleStmt", "editionStmt", "extent", "publicationStmt", "seriesStmt", "notesStmt", "sourceDesc"]
		},
		titleStmt: {
                    attrs: {
                        role: ["translator", "editor", "compiler", "illustrator"],
			resp: [""]
                    },
                    children: ["title", "author", "editor", "sponsor", "funder", "principal", "respStmt"]
                },
		editionStmt: {
                    attrs: {
                        name: null,
                    },
                    children: ["p", "edition"]
                },
		publicationStmt: {
                    attrs: {
			type: ["ISBN", "LCCN", "DOI"]
                    },
                    children: [ "p", "title", "idno", "respStmt"]
                },
		seriesStmt: {
                    attrs: {
                        status: ["free", "restricted", "unknown"],
			type: ["ISBN", "LCCN", "DOI"],
			when: [""]
                    },
                    children: ["publisher", "pubPlace", "date", "p", "distributor", "authority", "address", "idno", "availability", "date"]
                },
		sourceDesc: {
                    attrs: {
                        name: null,
                    },
                    children: ["p", "bibl", "biblStruct", "biblFull", "listBibl"]
                },
		encodingDesc: {
			attrs: {
				name: null,
			},
			children: ["editorialDecl", "projectDesc", "tagsDecl", "refsDecl", "classDecl"]
		},
		editorialDesc: {
			attrs: {
				status: null,
				source: null,
				method: null,
				marks: null,
				eol: null
			},
			children: ["correction", "normalization", "quotation", "hyphenation", "interpretation"]
		},
		projectDesc: {
			attrs: {
				name: null,
			},
			children: ["p"]
		},
		tagsDecl: {
			attrs: {
				gi: null,
				occurs: null,
				withId: null,
				render: null
			},
			children: ["namespace", "rendition"]
		},
		refsDecl: {
			attrs: {
				name: null,
			},
			children: ["p"]
		},
		classDecl: {
			attrs: {
				name: null,
			},
			children: ["taxonomy"]
		},
		metDecl: {
			attrs: {
				name: null,
			},
			children: ["p", "metSym"]
		},
		profileDesc: {
			attrs: {
				name: null,
			},
			children: ["creation", "langUsage", "textClass", "handNotes"]
		},
		revisionDesc: {
			attrs: {
				when: null,
				who: null
			},
			children: ["change"]
		},
		
		
		text: {
                    attrs: {
                        name: null,
                    },
                    children: ["body"]
                },
                body: {
                    attrs: {
                        name: null
                    },
                    children: ["div", "p", "head", "trailer", "lg", "l", "sp", "speaker", "stage",
			       "hi", "emph", "mentioned", "q", "quote", "note", "ref", "pb", "choice",
			       "orig", "reg", "sic", "corr", "add", "del", "gap", "unclear", "abbr", "expan",
			       "bibl", "title", "author", "epigraph", "opener", "closer", "dateline", "salute",
			       "signed", "docDate", "editor", "publicationStmt", "projectDesc"	]
                },
		
            };

            var cmLineNumbers = Drupal.settings['cm']['line_numbers'];
            var cmAutoTagClosing = Drupal.settings['cm']['auto_tag_closing'];
            var cmFontsize = Drupal.settings['cm']['cm_fontsize'];
            var cmLanguage = Drupal.settings['cm']['cm_lang'];

            $('fieldset.node-form-cm', context).drupalSetSummary(function (context) {
                if ($('.form-item-cm-enabled input', context).is(':checked')) {
                    return Drupal.t('CodeMirror enabled');
                } else {
                    return Drupal.t('CodeMirror disabled');
                }
            });

            var textarea = jQuery("#edit-body-und-0-value");
            var grippie = textarea.parents('.resizable-textarea').find('.grippie');

            // enables Codemirror with syntax highliting
            $('#edit-cm-enabled').change(function () {
                if ($('#edit-cm-enabled:checked').val() !== undefined) {
                    grippie.hide();
                    getEditor();
                    $(this).data('editor', editor);
                    $(this).addClass('cm');

                } else {
                    $(this).data('editor').toTextArea();
                    grippie.show();
                    $(this).removeClass('cm');
                }
            });

            // enables the line numbers for the editor textarea
            $('#edit-cm-line-numbers').change(function () {
                if ($('#edit-cm-line-numbers:checked').val() !== undefined) {
                    editor.setOption("lineNumbers", true);
                } else {
                    editor.setOption("lineNumbers", false);
                }
            });

            // enables auto tag closing
            $('#edit-cm-auto-tag-closing').change(function () {
                if ($('#edit-cm-auto-tag-closing:checked').val() !== undefined) {
                    editor.setOption("autoCloseTags", true);
                } else {
                    editor.setOption("autoCloseTags", false);
                }
            });

            // TODO: Auto Completion

            // adjusts the font size
            $('#edit-cm-cm-fontsize').change(function () {
                setFontsize($('#edit-cm-cm-fontsize option:selected').val());
            });


            // sets the textarea to the Codemirror editor
            // sets fontsize because CM doesnt support fontsize settings without editing css files on server
            function getEditor() {
                editor = CodeMirror.fromTextArea(textarea.get(0), {
                    mode: 'xml',
                    height: "140px",
                    lineWrapping: true,
                    lineNumbers: cmLineNumbers,
                    gutter: true,
                    autoCloseTags: cmAutoTagClosing,
                    extraKeys: {
                        "'<'": completeAfter,
                        "'/'": completeIfAfterLt,
                        "' '": completeIfInTag,
                        "'='": completeIfInTag,
                        "Shift-Ctrl-Space": function (cm) {
                            CodeMirror.showHint(cm, CodeMirror.hint.xml, {
                                schemaInfo: tags
                            });
                        }
                    },

                });
                setFontsize(cmFontsize);
            }

            function completeAfter(cm, pred) {
                var cur = cm.getCursor();
                if (!pred || pred()) setTimeout(function () {
                    if (!cm.state.completionActive)
                        CodeMirror.showHint(cm, CodeMirror.hint.xml, {
                            schemaInfo: tags,
                            completeSingle: false
                        });
                }, 100);
                return CodeMirror.Pass;
            }

            function completeIfAfterLt(cm) {
                return completeAfter(cm, function () {
                    var cur = cm.getCursor();
                    return cm.getRange(CodeMirror.Pos(cur.line, cur.ch - 1), cur) == "<";
                });
            }

            function completeIfInTag(cm) {
                return completeAfter(cm, function () {
                    var tok = cm.getTokenAt(cm.getCursor());
                    if (tok.type == "string" && (!/['"]/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1)) return false;
                    var inner = CodeMirror.innerMode(cm.getMode(), tok.state).state;
                    return inner.tagName;
                });
            }

            // set font size
            function setFontsize(n) {
                switch (n) {
                case '9pt':
                    $('div.CodeMirror').css({
                        "font-size": "9pt"
                    });
                    break;
                case '10pt':
                    $('div.CodeMirror').css({
                        "font-size": "10pt"
                    });
                    break;
                case '11pt':
                    $('div.CodeMirror').css({
                        "font-size": "11pt"
                    });
                    break;
                case '12pt':
                    $('div.CodeMirror').css({
                        "font-size": "12pt"
                    });
                    break;
                default:
                    $('div.CodeMirror').css({
                        "font-size": "11pt"
                    });
                    alert("default executed: font-size gets default");
                }
            }
        }

    };

})(jQuery);